首先看一下使用方法,然後再來大致解析一下用法和緣由吧。
一般在 AOSP 環境下要先執行下面命令才可以使用:
$ source build/envsetup.sh
$ lunch <DEVICE_NAME>
舉例這次 <DEVICE_NAME>
是用 aosp_marlin-userdebug
再加上 -h 參數就可以看到用法如下:
$ hidl-gen -h
usage: hidl-gen [-p <root path>] -o <output path> -L <language> [-O <owner>] (-r <interface root>)+ [-v] [-d <depfile>] FQNAME...
Process FQNAME, PACKAGE(.SUBPACKAGE)*@[0-9]+.[0-9]+(::TYPE)?, to create output.
-h: Prints this menu.
-L <language>: The following options are available:
check : Parses the interface to see if valid but doesn't write any files.
c++ : (internal) (deprecated) Generates C++ interface files for talking to HIDL interfaces.
c++-headers : (internal) Generates C++ headers for interface files for talking to HIDL interfaces.
c++-sources : (internal) Generates C++ sources for interface files for talking to HIDL interfaces.
export-header : Generates a header file from @export enumerations to help maintain legacy code.
c++-impl : Generates boilerplate implementation of a hidl interface in C++ (for convenience).
c++-impl-headers: c++-impl but headers only
c++-impl-sources: c++-impl but sources only
c++-adapter : Takes a x.(y+n) interface and mocks an x.y interface.
c++-adapter-headers: c++-adapter but helper headers only
c++-adapter-sources: c++-adapter but helper sources only
c++-adapter-main: c++-adapter but the adapter binary source only
java : (internal) Generates Java library for talking to HIDL interfaces in Java.
java-constants : (internal) Like export-header but for Java (always created by -Lmakefile if @export exists).
vts : (internal) Generates vts proto files for use in vtsd.
makefile : (removed) Used to generate makefiles for -Ljava and -Ljava-constants.
androidbp : (internal) Generates Soong bp files for -Lc++-headers, -Lc++-sources, -Ljava, -Ljava-constants, and -Lc++-adapter.
androidbp-impl : Generates boilerplate bp files for implementation created with -Lc++-impl.
hash : Prints hashes of interface in `current.txt` format to standard out.
-O <owner>: The owner of the module for -Landroidbp(-impl)?.
-o <output path>: Location to output files.
-p <root path>: Android build root, defaults to $ANDROID_BUILD_TOP or pwd.
-r <package:path root>: E.g., android.hardware:hardware/interfaces.
-v: verbose output.
-d <depfile>: location of depfile to write to.
在 Android 8.0 以上的版本中,改寫了大部分的 HAL 架構為 HIDL。
hardware/interfaces/update-makefiles.sh
可以創建編譯 HIDL 文件的 Android.bp
1 #!/bin/bash
2
3 source $ANDROID_BUILD_TOP/system/tools/hidl/update-makefiles-helper.sh
4
5 do_makefiles_update \
6 "android.hardware:hardware/interfaces" \
7 "android.hidl:system/libhidl/transport"
8
可以看到 hidl-gen 真正的程式碼位置是在 system/tools/hidl/
中
通過 update-makefiles.sh
可以創建和編輯 HIDL 文件的 Android.bp
假設我們創建一個叫 helloworld 的模塊,
在 hardware/interfaces
底下建立一個 helloworld/1.0/IHelloWorld.hal
1 package android.hardware.helloworld@1.0;
2
3 interface IHelloWorld {
4 justTest(string name);
5 };
之後回到 AOSP 根目錄執行 update-makefiles.sh
$ ./hardware/interfaces/update-makefiles.sh
就可以在 hardware/interfaces/helloworld/1.0/
底下生成 Android.bp
1 // This file is autogenerated by hidl-gen -Landroidbp.
2
3 hidl_interface {
4 name: "android.hardware.helloworld@1.0",
5 root: "android.hardware",
6 vndk: {
7 enabled: true,
8 },
9 srcs: [
10 "IHelloWorld.hal",
11 ],
12 interfaces: [
13 "android.hidl.base@1.0",
14 ],
15 gen_java: true,
16 }
17
name:FQname 的全名
root:定義好的 package root 名稱
interfaces:編譯過程中依賴的接口名稱,就像 C 中的 Library
gen_java:是否編譯為 JAVA 使用的接口
當然還有其他參數,例如 gen_java_constants 設為 true 的時候,
會生成為 Java 使用的 Constants 類。
IHelloWorld.hal 和對應的 Android.bp 創建好後,
就可以根據需要實現 FQName-impl 和 FQName-service所需要的文件,
而這些文件也是通過 hidl-gen 創建的,就是新增下面這個腳本。
1 #! /bin/bash
2 PACKAGE=android.hardware.helloworld@1.0
3 LOC=$ANDROID_BUILD_TOP/hardware/interfaces/helloworld/1.0/default/
4
5 hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces \
6 -randroid.hidl:system/libhidl/transport $PACKAGE
7 hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces \
8 -randroid.hidl:system/libhidl/transport $PACKAGE
執行後就會產生出 default 底下的檔案:
.
└── 1.0
├── Android.bp
├── default
│ ├── Android.bp
│ ├── HelloWorld.cpp
│ └── HelloWorld.h
└── IHelloWorld.hal
稍微看一下裡面的 Android.bp:
1 cc_library_shared {
2 // FIXME: this should only be -impl for a passthrough hal.
3 // In most cases, to convert this to a binderized implementation, you should:
4 // - change '-impl' to '-service' here and make it a cc_binary instead of a
5 // cc_library_shared.
6 // - add a *.rc file for this module.
7* *// - delete HIDL_FETCH_I* functions.
8 // - call configureRpcThreadpool and registerAsService on the instance.
9 // You may also want to append '-impl/-service' with a specific identifier like
10 // '-vendor' or '-<hardware identifier>' etc to distinguish it.
11 name: "android.hardware.helloworld@1.0-impl",
12 relative_install_path: "hw",
13 // FIXME: this should be 'vendor: true' for modules that will eventually be
14 // on AOSP.
15 proprietary: true,
16 srcs: [
17 "HelloWorld.cpp",
18 ],
19 shared_libs: [
20 "libhidlbase",
21 "libhidltransport",
22 "libutils",
23 "android.hardware.helloworld@1.0",
24 ],
25 }
如註釋部分,可以根據特殊的需要進行修改,
例如 vendor 需要設為true,這樣編譯出來的so位於vendor下面,而不是system。
也可以使用同樣的方式為 FQName-service 創建對應的規則。